namespace NUnitTests{
    using System;
    using System.Threading;
    using System.Windows.Automation;
    using Guia.Core;
    using Guia.Elements;
    using Guia.Locator;
    using NUnit.Framework;
    using WpfTestApplication;

    /// <summary>
    /// Summary description for UIElementTest
    /// </summary>
    [TestFixture]
    public class UIElementTest : AbstractWindowTest
    {
        protected override Type TestWindowType()
        {
            return typeof(UIElementTestWindow);
        }

        protected override string TestWindowName()
        {
            return "UIElementTestWindow";
        }

        [Test]
        public void TestGetAllLabelsTyped()
        {
            Label[] labels = window.GetAll<Label>();
            Assert.AreEqual(3, labels.Length);
            Assert.AreEqual("label1", labels[0].AutomationId);
            Assert.AreEqual("label2", labels[1].AutomationId);
            Assert.AreEqual("label3", labels[2].AutomationId);
        }

        [Test]
        public void TestGetAllButtonsTyped()
        {
            Button[] buttons = window.GetAll<Button>();
            Assert.AreEqual(5, buttons.Length);
            Assert.AreEqual("Minimize", buttons[0].AutomationId);
            Assert.AreEqual("Maximize", buttons[1].AutomationId);
            Assert.AreEqual("Close", buttons[2].AutomationId);
            Assert.AreEqual("Button", buttons[3].TextValue);
            Assert.AreEqual("Disabled Button", buttons[4].TextValue);
        }

        [Test, ExpectedException(typeof(ElementNotEnabledException))]
        public void TestDisabled()
        {
            Button disabledButton = window.Get<Button>("buttonDisabled");
            Assert.AreEqual(false, disabledButton.IsEnabled);
            disabledButton.Invoke();
        }

        [Test]
        public void TestToolTip()
        {
            Label label1 = window.Get<Label>("label1");
            Assert.AreEqual("This is a tooltip!", label1.ToolTip);
            Label labelNoTooltip = window.Get<Label>("label2");
            Assert.AreEqual("", labelNoTooltip.ToolTip);
        }

        [Test]
        public void TestGetLabelTypedWithAutomationId()
        {
            Label label = window.Get<Label>("label1");
            Assert.IsNotNull(label);
            Assert.AreEqual("label1", label.AutomationId);
            Assert.AreEqual("Label 1", label.TextValue);
        }

        [Test]
        public void TestGetLabelTypedWithName()
        {
            Label label = window.GetByName<Label>("Label 1");
            Assert.IsNotNull(label);
            Assert.AreEqual("label1", label.AutomationId);
            Assert.AreEqual("Label 1", label.TextValue);
        }

        [Test]
        public void TestGetLabelTypedWithSearchCondition()
        {
            Label label = window.Get<Label>(SearchCondition.ByName("Label 2"));
            Assert.IsNotNull(label);
            Assert.AreEqual("label2", label.AutomationId);
            Assert.AreEqual("Label 2", label.TextValue);
        }

        [Test]
        public void TestGetAllLabelsTypedWithSearchCondition()
        {
            Label[] labels = window.GetAll<Label>(SearchCondition.ByName("Label 1"));
            Assert.AreEqual(2, labels.Length);
            Assert.AreEqual("Label 1", labels[0].TextValue);
            Assert.AreEqual("Label 1", labels[1].TextValue);
            Assert.AreEqual("label1", labels[0].AutomationId);
            Assert.AreEqual("label3", labels[1].AutomationId);
        }

        [Test]
        public void TestGetLabelWithSearchCondition()
        {
            UiElement uiElement = window.Get(SearchCondition.ByName("Label 2"));
            Assert.IsNotNull(uiElement);
            Assert.AreEqual("label2", uiElement.AutomationId);
            Assert.AreEqual("Label 2", uiElement.Name);
        }

        [Test]
        public void TestGetLabelWithName()
        {
            UiElement uiElement = window.GetByName("Label 2");
            Assert.IsNotNull(uiElement);
            Assert.AreEqual("label2", uiElement.AutomationId);
            Assert.AreEqual("Label 2", uiElement.Name);
        }

        [Test]
        public void TestGetAllLabelsWithSearchCondition()
        {
            UiElement[] uiElements = window.GetAll(SearchCondition.ByName("Label 1"));
            Assert.AreEqual(2, uiElements.Length);
            Assert.AreEqual("Label 1", uiElements[0].Name);
            Assert.AreEqual("Label 1", uiElements[1].Name);
            Assert.AreEqual("label1", uiElements[0].AutomationId);
            Assert.AreEqual("label3", uiElements[1].AutomationId);
        }

        [Test]
        public void TestGetAllUIElements()
        {
            UiElement[] uiElements = UiElementFactory.GetAllUiElements(window);
            Assert.AreEqual(11,uiElements.Length);
        }

        [Test]
        public void TestGetPattern()
        {
            InvokePattern invokePattern = window.Get<Button>("button1").GetPattern<InvokePattern>();
            Assert.IsNotNull(invokePattern);
            WindowPattern windowPattern = window.GetPattern<WindowPattern>();
            Assert.IsNotNull(windowPattern);
        }

        [Test,ExpectedException(typeof(OperationNotSupportedException))]
        public void TestGetPatternNotSupported()
        {
            window.GetPattern<InvokePattern>();
        }

        [Test,ExpectedException(typeof(ArgumentNullException))]
        public void TestConstructorArgumentNull()
        {
            new UiElement(null);
        }

        [Test]
        public void TestClickRight()
        {
            Label label1 = this.window.Get<Label>("label1");
            label1.ClickRight();
            Delay.ForMilliseconds(500);
            Assert.AreEqual("Mouse clicked right", label1.TextValue);
        }

        [Test]
        public void TestClickLeft()
        {
            Label label1 = this.window.Get<Label>("label1");
            label1.ClickLeft();
            Delay.ForMilliseconds(500);
            Assert.AreEqual("Mouse clicked left", label1.TextValue);
        }

        [Test]
        public void TestDoubleClick()
        {
            Label label2 = this.window.Get<Label>("label2");
            label2.DoubleClick();
            Delay.ForMilliseconds(500);
            Assert.AreEqual("Mouse double clicked", label2.TextValue);
        }

        [Test]
        public void TestGetControlType()
        {
            Label label = window.Get<Label>("label1");
            Assert.AreEqual(ControlType.Text,label.ControlType);
        }

        [Test]
        public void TestGetParentElement()
        {
            Label label = window.Get<Label>("label1");
            Assert.AreEqual("label1", label.AutomationId);
            UiElement parentElement = label.ParentElement;
            Assert.AreEqual("UIElementTestWindow", parentElement.Name);
            Assert.AreEqual(UiElement.RootElement, parentElement.ParentElement);
        }

        [Test]
        public void TestParentWindow()
        {
            Label label = window.Get<Label>("label1");
            Assert.IsTrue(window.AutomationElement == label.ParentWindow.AutomationElement);
        }

        [Test]
        [ExpectedException(typeof(OperationNotSupportedException))]
        public void TestNoParentWindow()
        {
            Assert.IsTrue(window.AutomationElement == window.ParentWindow.AutomationElement);
        }

        [Test]
        public void TestEquals()
        {
            Label label = window.Get<Label>("label1");
            Label sameLabel = window.Get<Label>("label1");
            Assert.IsTrue(label.Equals(sameLabel));

            Label differentLabel = window.Get<Label>("label2");
            Assert.IsFalse(label.Equals(differentLabel));
        }
    }
}
